package Server;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import Commons.Karte;
import Commons.Spieler;
import Commons.Spielzustand;

public class Spiellogik {

	public Spielzustand spielzustand = null;

	// Singleton Pattern
	public Spielzustand getSpielzustand() {
		if (spielzustand == null) {
			this.spielzustand = new Spielzustand();
			return spielzustand;
		}
		return spielzustand;
	}

	// todo synchronized
	public synchronized void setSpielzustand(Spielzustand spielzustand) {
		this.spielzustand = spielzustand;
		System.out.println("Server- Spieler1:"
				+ spielzustand.getSpieler(0).isGegnerHatGespielt()
				+ "; Spieler2:"
				+ spielzustand.getSpieler(1).isGegnerHatGespielt());
	}

	public Spiellogik() {
		System.out.println("Spiellogik initialisiert.");
	}

	public String getTest() {

		return "Einfache Methode";
	}

	// 1. Client Spielerlaubnis abfragen
	// falls false, soll eine Fehlermeldung kommen
	// falls true, spielen methode aufrufen
	public boolean getSpielErlaubnis(ArrayList<Karte> zuSpielendeKarten) {
		if ((getStrasseMitJokerkarten(zuSpielendeKarten)
				|| getSet(zuSpielendeKarten) || getEineKarte(zuSpielendeKarten))
				&& getMindestensEineNormaleKarte(zuSpielendeKarten))
			return true;
		return false;
	}

	public boolean getMindestensEineNormaleKarte(
			ArrayList<Karte> zuSpielendeKarten) {

		for (Karte karte : zuSpielendeKarten) {
			if (karte.isJoker() == false) {
				System.out
						.println("Mindestens eine normale Karte ist vorhanden");
				return true;
			}
		}
		System.out.println("keine normale Karte ist vorhanden");
		return false;
	}

	public boolean getStrasseMitJokerkarten(ArrayList<Karte> zuSpielendeKarten) {

		if (zuSpielendeKarten.size() <= 2) {
			System.out
					.println("Es muessen mindestens 3 Karten eine Strasse sein");

			return false;
		}
		ArrayList<Karte> jokerKarten = new ArrayList<Karte>();
		ArrayList<Karte> normaleKarten = new ArrayList<Karte>();

		for (Karte karte : zuSpielendeKarten) {
			System.out.println("Jokerkarte " + karte.isJoker());
			if (karte.isJoker()) {

				jokerKarten.add(karte);
			} else {
				normaleKarten.add(karte);
			}
		}

		if (!getStrasse(normaleKarten) || (jokerKarten.size() != 0)) {
			return ueberpruefeObLueckeGeschlossenWerdenKann(jokerKarten,
					normaleKarten);

		} else {
			System.out.println("Alles wunderbar");
			return true;

		}

	}

	public boolean ueberpruefeObLueckeGeschlossenWerdenKann(
			ArrayList<Karte> jokerKarten, ArrayList<Karte> normaleKarten) {
		// sortieren der Karten aufsteigend

		int[] raenge = new int[normaleKarten.size()];

		Collections.sort(normaleKarten);

		ArrayList<Integer> paerchen = new ArrayList<>();

		for (int i = 0; i < 10; i++) {
			int paerchenGroesse = 0;
			for (Karte karte : normaleKarten) {

				if (karte.getRang() == (i + 2)) {
					if (paerchenGroesse == 0) {
						paerchenGroesse++;
						paerchen.add(paerchenGroesse);
					} else {
						paerchenGroesse++;
						paerchen.set(paerchen.size() - 1, paerchenGroesse);
					}
				}
			}
		}

		for (Integer paerchenGroesse : paerchen) {
			System.out.println("raengeGroesseList " + paerchenGroesse);

		}
		// ermittel letzte Position wo ein Rang vorkommt und hoechsten Rangwert
		int max = 0;

		for (Integer paerchenGroesse : paerchen) {
			if (paerchenGroesse > max) {
				max = paerchenGroesse;
			}
		}
		System.out.println("Max " + max);

		int differenz = 0;
		int arrayListIndex = 1;
		int fehlendeRaenge = 0;
		int gesuchteJokerkarten = 0;

		// ermittel fehlende Raenge
		for (Karte karte : normaleKarten) {

			if (arrayListIndex < normaleKarten.size()) {

				differenz = normaleKarten.get(arrayListIndex).getRang()
						- karte.getRang();
				if (differenz > 1) {
					fehlendeRaenge += (differenz - 1);
				}
			}
			arrayListIndex++;
		}
		System.out.println("Fehlende fehlendeRaenge " + fehlendeRaenge);

		// ermittel kleine Paerchen
		for (Integer paerchenGroesse : paerchen) {
			int tmp = max - paerchenGroesse;
			if (tmp > 0) {
				gesuchteJokerkarten += tmp;
			}
		}

		gesuchteJokerkarten += (fehlendeRaenge * max);

		System.out.println("Anzahl fehlender Jokerkarten "
				+ gesuchteJokerkarten);
		int rest = 0;

		rest = jokerKarten.size() - gesuchteJokerkarten;
		System.out.println("Max " + max + " Rest " + rest);

		if (rest < 0) {
			System.out
					.println("Jokerkarten konnten die fehlenden Karten nicht abdecken");
			return false;
		}
		if (max > 1 && rest > 0 && max - rest != 0) {
			System.out.println("zu wenig Jokerkarten fuer eine Strasse");
			return false;
		}

		System.out.println("Strasse");
		return true;
	}

	public boolean getJokerKartenAbNeun(ArrayList<Karte> jokerKarten,
			ArrayList<Karte> normaleKarten, int anzahlGesuchterJokerkarten) {
		int rest;

		Collections.sort(jokerKarten);

		Karte[] jokerArray = new Karte[jokerKarten.size()];
		int i = 0;
		for (Karte karte : jokerKarten) {
			jokerArray[i] = karte;
			i++;
		}

		i = 0;
		boolean zehner = false;
		for (Karte normaleKarte : normaleKarten) {
			if (normaleKarte.getRang() == 10)
				zehner = true;

		}
		rest = jokerKarten.size() - anzahlGesuchterJokerkarten;
		System.out.println("Zehner " + zehner + " Rest " + rest
				+ " anzahlGesuchterJokerkarte " + anzahlGesuchterJokerkarten);
		if (zehner == true && rest >= 2) {
			for (int j = 0; j < jokerArray.length - anzahlGesuchterJokerkarten; j++) {
				if (jokerArray[j].getRang() < jokerArray[j + 1].getRang()) {
					System.out
							.println("Strasse kann nicht um Jokerkarten erweitert werden");
					return false;

				}
			}
		}
		System.out.println("Strasse mit Joker");
		return true;
	}

	public boolean getStrasse(ArrayList<Karte> zuSpielendeKarten) {
		int[] raenge = new int[zuSpielendeKarten.size()];
		int i = 0;
		int differenz = 0;
		int zaehleGleichePaerchenGroesse = 1;

		// ueberpruefe ob nur eine Karte existiert
		if (zuSpielendeKarten.size() == 1) {
			System.out.println("Es existiert nur eine Karte");
			return false;
		}
		// ueberpruefe auf unterschiedliche Farben
		String[] farben = { "rot", "grau", "gruen", "gelb" };
		boolean[] unterschiedlicheFarben = new boolean[4];
		
		for (String farbe : farben) {
			for (Karte karte : zuSpielendeKarten) {
				if (karte.getFarbe().equals(farbe)) {

					unterschiedlicheFarben[i] = true;
				}

			}
			i++;
		}
		i = 0;
		
		int anzahlUnterschiedlicherFarben = 0;
		for (boolean unterschiedlicheFarbe : unterschiedlicheFarben) {

			// System.out.println("Unterschiedliche Farben "
			// + unterschiedlicheFarbe);

			if (unterschiedlicheFarbe == true)
				anzahlUnterschiedlicherFarben++;

			if (anzahlUnterschiedlicherFarben > 1) {
				System.out.println("Es gibt unterschiedliche Farben");
				return false;
			}
		}

		// sortieren der Karten aufsteigend
		Collections.sort(zuSpielendeKarten);

		// befuellen des Arrays raenge mit karte.getRang() durch eine Iteration.
		for (Karte karte : zuSpielendeKarten) {
			raenge[i] = karte.getRang();
			i++;
		}

		// Ueberpruefe ob die Differenz der beiden Kartenenraenge mehr als 1
		// ist.
		for (int j = 0; j < raenge.length - 1; j++) {

			differenz = raenge[1 + j] - raenge[0 + j];
			if (differenz > 1) {
				System.out.println("Differenz ist zu gross");
				return false;
			}
		}

		// Ueberpruefe ob einfache Strasse
		int mindestensDrei = 0;
		boolean paerchen = false;
		for (int j = 0; j < raenge.length - 1; j++) {
			if (raenge[1 + j] == raenge[0 + j]) {

				paerchen = true;
			} else {
				mindestensDrei++;
			}

		}
		if (!paerchen && mindestensDrei >= 2) {
			System.out.println("Einfache Strasse");

			return true;
		} else if (!paerchen) {
			System.out.println("Weder Paerchenstrasse noch einfache Strasse");
			return false;

		}
		
		boolean kleineStrasse = false;
		boolean naechstePaerchen = false;
		for (int j = 0; j < raenge.length - 1; j++) {
			if (j == 0) {
				if (raenge[1 + j] != raenge[0 + j]) {
					kleineStrasse = true;
				}
			} else if (raenge[1 + j] == raenge[0 + j]) {
				naechstePaerchen = true;
			}
		}
		if (kleineStrasse && naechstePaerchen) {
			System.out
					.println("Es existiert eine kleine Strasse und ein Paerchen, deshalb insgesamt keine Strasse");
			return false;
		}

		// Ueberpruefe ob kleine und paerchen Strasse
		for (int j = 0; j < raenge.length - 1; j++) {
			if (raenge[1 + j] != raenge[0 + j]) {
				paerchen = true;
			}
		}
		
		return paerchenErmitteln(raenge);

	}

	public boolean paerchenErmitteln(int[] raenge) {
		// Ueberpruefe Paerchenstrasse
		ArrayList<Integer> gezaehlteGleichePaerchen = new ArrayList<Integer>();
		int zaehlPaerchen = 0;
		int zaehlUngleichePaerchen = 0;
		
		// ermittel paerchen
		for (int j = 0; j < raenge.length - 1; j++) {
			if (raenge[1 + j] == raenge[0 + j]) {
				zaehlPaerchen++;
				if (zaehlPaerchen > 1)
					gezaehlteGleichePaerchen.set(
							gezaehlteGleichePaerchen.size() - 1, zaehlPaerchen);
				else {
					gezaehlteGleichePaerchen.add(zaehlPaerchen);
					System.out.println("gezaehlteGleichePaerchen "
							+ gezaehlteGleichePaerchen.size());

				}
			} else {

				zaehlPaerchen = 0;
				zaehlUngleichePaerchen++;
			}

		}

		if (zaehlUngleichePaerchen == gezaehlteGleichePaerchen.size()) {
			System.out
					.println("gleiche Paerchen entsprechen ungleiche Paerchen");
			return false;
		}

		int merkeErstePaerchenGroesse = gezaehlteGleichePaerchen.get(0);

		// Ueberpruefe ob ein einfaches Paerchen existiert
		if (gezaehlteGleichePaerchen.size() < 2) {
			System.out.println("Es gibt nur ein Paerchen");
			return false;
		}

		// Ueberpruefe gezaehltenGleicheRaenge
		for (int paerchenGroesse : gezaehlteGleichePaerchen) {

			if (merkeErstePaerchenGroesse != paerchenGroesse) {
				System.out.println("Paerchen sind nicht gleich gross");
				return false;
			}
		}

		System.out.println("Paerchen Strasse!");
		return true;
	}

	public int getPunkte(ArrayList<Karte> gespielteKarten) {
		int punkte = 0;
		for (Karte karte : gespielteKarten) {
			punkte += karte.getPunkte();
		}

		return punkte;
	}

	public boolean getSet(ArrayList<Karte> zuSpielendeKarten) {
		int vergleicheRangWerte = 0;
		vergleicheRangWerte = zuSpielendeKarten.get(0).getRang();
		ArrayList<Karte> jokerKarten = new ArrayList<>();
		ArrayList<Karte> normaleKarten = new ArrayList<>();

		for (Karte karte : zuSpielendeKarten) {
			if (karte.isJoker()) {
				jokerKarten.add(karte);
			} else {
				normaleKarten.add(karte);
			}
		}
		for (Karte karte : normaleKarten) {
			if (vergleicheRangWerte != karte.getRang()) {
				return false;
			}
		}

		return true;
	}

	public boolean getEineKarte(ArrayList<Karte> zuSpielendeKarten) {
		if (zuSpielendeKarten.size() == 1)
			return true;
		return false;
	}

	// Erster Spieler ermitteln
	/**
	 * @param spieler1
	 * @param spieler2
	 */
	public void ersterSpielerErmitteln(Spieler spieler1, Spieler spieler2) {
		int zufallsZahl = 0;
		Random random = new Random();
		zufallsZahl = random.nextInt(2) + 1;
		if (zufallsZahl == 1) {
			spieler1.setRundenBeginner(true);
			spieler1.setBlockiert(false);
		} else if (zufallsZahl == 2) {
			spieler2.setRundenBeginner(true);
			spieler2.setBlockiert(false);
		}

	}

	public boolean spielSiegerErmitteln(Spieler spieler,
			Spielzustand spielzustand) {
		if (spieler.getGesammeltenPunkte() >= spielzustand.getZiellinie()) {
			spieler.setSieger(true);
			DBZugriff.tabelleAusgeben();
			return true;
		}
		return false;

	}

	// gesamtePunkteErmitteln (neu) = gesamtePunkteErmitteln (alt) + stichpunkte
	// + haggis + gegnerPunkte

	public boolean rundenGewinnerErmitteln(Spieler spieler1, Spieler spieler2,
			Spielzustand spielzustand) throws UnknownHostException,
			ClassNotFoundException, IOException {
		if(getSpielzustand().getSpieler(0).getGesammeltenPunkte() >= getSpielzustand().getZiellinie()){
			getSpielzustand().getSpieler(0).setSieger(true);
			getSpielzustand().getSpieler(1).setSieger(false);
		}
		if(getSpielzustand().getSpieler(1).getGesammeltenPunkte() >= getSpielzustand().getZiellinie()){
			getSpielzustand().getSpieler(1).setSieger(true);
			getSpielzustand().getSpieler(0).setSieger(false);
		}
		
		
		HaggisRandom haggisRandom = new HaggisRandom();

		

		System.out
				.println("------------------------------rundenGewinner ermitteln--------------------------");
		System.out.println("---------------------Spieler 1 kann spielen "
				+ spieler1.isHatGespielt());
		// spieler 1
		if (spieler1.getZuSpielendenKarten() != null
				&& spieler1.isHatGespielt()) {

			System.out
					.println("------------------------------ spieler1.getZuSpielendenKarten() --------------------------");

			int kartenBestand = 0;
			
			
			
			
			kartenBestand = spieler1.getKartenBestand()
					- spieler1.getZuSpielendenKarten().size();
			System.out.println("********************KartenBestand = " + kartenBestand + " alter KartenBestand  "  + spieler1.getKartenBestand()  + " zuspielende Karten  " + spieler1.getZuSpielendenKarten().size());
			System.out
					.println("----------------------------------Kartenbestand "
							+ kartenBestand);
			spieler1.setKartenBestand(kartenBestand);

			if (kartenBestand <= 0) {
				getSpielzustand().getSpieler(0).setZuSpielendenKarten(new ArrayList<Karte>());
				getSpielzustand().getSpieler(0).setRundenBeginner(true);
				getSpielzustand().getSpieler(0).setKartenBestand(17);
				spieler1.setKeineKarten(true);
				getSpielzustand().setGemischteKartenAngekommen(false);
				haggisRandom.setVierzehnSpieler1(new ArrayList<Karte>());
				haggisRandom.setVierzehnSpieler2(new ArrayList<Karte>());
				haggisRandom.generateHaggisKarten();
				DBZugriff.aktualisierepunktestand(getSpielzustand().getSpieler(0).getSpielername(),
						getSpielzustand().getSpieler(0).getGesammeltenPunkte());
				
				getSpielzustand().getSpieler(0).setVierzehnSpieler1(haggisRandom.getVierzehnSpieler1());
				
				int i = 0;
				for(Karte vierzehnkarte : getSpielzustand().getSpieler(0).getVierzehnSpieler1())
				{
					System.out.println(i+ " ******************* Vierzehnkarten      " + vierzehnkarte.getRang());
					i++;
				}
				
				i = 0;
				getSpielzustand().getSpieler(1).setVierzehnSpieler2(haggisRandom.getVierzehnSpieler2());
				
				for(Karte vierzehnkarte : getSpielzustand().getSpieler(1).getVierzehnSpieler2())
				{
					System.out.println(i+ "******************* Vierzehnkarten      " + vierzehnkarte.getRang());
					i++;
				}
				
				
				
				getSpielzustand().getSpieler(0).setRundenGewinner(true);
				getSpielzustand().getSpieler(1).setRundenGewinner(false);
				
				naechsterRundenBeginnnerErmitteln();
				
				return true;
			}

		}
		System.out.println("---------------------Spieler 2 kann spielen "
				+ spieler2.isHatGespielt());

		// spieler 2
		if (spieler2.getZuSpielendenKarten() != null
				&& spieler2.isHatGespielt()) {

			System.out
					.println("------------------------------ spieler2.getZuSpielendenKarten() --------------------------");

			int kartenBestand = 0;
			kartenBestand = spieler2.getKartenBestand()
					- spieler2.getZuSpielendenKarten().size();
			System.out.println("********************KartenBestand = " + kartenBestand + " alter KartenBestand  "  + spieler2.getKartenBestand()  + " zuspielende Karten  " + spieler2.getZuSpielendenKarten().size());
			System.out
					.println("----------------------------------Kartenbestand "
							+ kartenBestand);
			spieler2.setKartenBestand(kartenBestand);

			if (kartenBestand <= 0) {
				getSpielzustand().getSpieler(1).setZuSpielendenKarten(new ArrayList<Karte>());
				haggisRandom.setVierzehnSpieler1(new ArrayList<Karte>());
				haggisRandom.setVierzehnSpieler2(new ArrayList<Karte>());
				haggisRandom.generateHaggisKarten();
				getSpielzustand().getSpieler(1).setRundenBeginner(true);
				getSpielzustand().getSpieler(1).setKartenBestand(17);
				spieler2.setKeineKarten(true);
				getSpielzustand().setGemischteKartenAngekommen(false);
				haggisRandom.generateHaggisKarten();
				getSpielzustand().getSpieler(0).setVierzehnSpieler1(haggisRandom.getVierzehnSpieler1());
				
				DBZugriff.aktualisierepunktestand(getSpielzustand().getSpieler(1).getSpielername(),
						getSpielzustand().getSpieler(1).getGesammeltenPunkte());
				int i = 0;
				for(Karte vierzehnkarte : getSpielzustand().getSpieler(0).getVierzehnSpieler1())
				{
					System.out.println(i+ " ******************* Vierzehnkarten      " + vierzehnkarte.getRang());
				}
				
				i = 0;
				getSpielzustand().getSpieler(1).setVierzehnSpieler2(haggisRandom.getVierzehnSpieler2());
				
				for(Karte vierzehnkarte : getSpielzustand().getSpieler(1).getVierzehnSpieler2())
				{
					System.out.println(i+ "******************* Vierzehnkarten      " + vierzehnkarte.getRang());
				}
				
				System.out
						.println("-------------------------Spieler 2 hat keine Karten mehr");
				getSpielzustand().getSpieler(0).setRundenGewinner(false);
				getSpielzustand().getSpieler(1).setRundenGewinner(true);
				
				naechsterRundenBeginnnerErmitteln();
				
				return true;
			}
		}
		return false;
	}

	public void naechsterRundenBeginnnerErmitteln() {
		int gesammeltenPunkteSpieler1 = getSpielzustand().getSpieler(0).getGesammeltenPunkte(); 
		int gesammeltenPunkteSpieler2 = getSpielzustand().getSpieler(1).getGesammeltenPunkte();
		
		
		System.out
				.println("-------------------------Spieler 1 hat keine Karten mehr");
		
		if(gesammeltenPunkteSpieler1 < gesammeltenPunkteSpieler2){
			getSpielzustand().getSpieler(0).setRundenBeginner(true);
		 
		}else
		{
			getSpielzustand().getSpieler(1).setRundenBeginner(true);
			
		}
	}

	public int rundenPunkteErmitteln(Spieler spieler1, Spieler spieler2,
			ArrayList<Karte> vierzehnKarten, Spielzustand spielzustand) {
		spieler1.setRundenGewinner(true);
		int kumuliertHaggisPunkte = 0;
		int gesammeltenPunkte = 0;
		ArrayList<Karte> haggisKarten = spielzustand.getHaggis();
		for (Karte haggisKarte : haggisKarten) {
			kumuliertHaggisPunkte += haggisKarte.getPunkte();

		}

		System.out.println("kummulierte Punkte " + kumuliertHaggisPunkte);

		int gegnerischerPunkte = vierzehnKarten.size() * 5;
		System.out.println(" gegnerischerPunkte " + gegnerischerPunkte);
		int gesamtPunkte = spieler1.getGesammeltenPunkte();
		gesammeltenPunkte = spieler1.getGesammeltenPunkte()
				+ spielzustand.getUmkaempftePunkte() + kumuliertHaggisPunkte
				+ gesamtPunkte + gegnerischerPunkte;
		
		if (spieler1.getGesammeltenPunkte() > spieler2.getGesammeltenPunkte()) {
			spieler2.setBlockiert(false);
			spieler1.setBlockiert(true);
		} else {
			spieler2.setBlockiert(true);
			spieler1.setBlockiert(false);
		}
		if (spieler1.getGesammeltenPunkte() == spieler2.getGesammeltenPunkte()) {
			if (spieler1.isRundenGewinner() == true) {
				spieler1.setRundenBeginner(false);
				spieler2.setRundenBeginner(true);

			} else {
				spieler1.setRundenBeginner(true);
				spieler2.setRundenBeginner(false);

			}

		}

		return gesammeltenPunkte;
	}

	public int rundenPunkteErmitteln2(Spieler spieler, Spieler gegenspieler,
			ArrayList<Karte> vierzehnKarten, Spielzustand spielzustand) {
		spieler.setRundenGewinner(true);
		int kumuliertHaggisPunkte = 0;
		int gesammeltenPunkte = 0;
		ArrayList<Karte> haggisKarten = spielzustand.getHaggis();
		for (Karte haggisKarte : haggisKarten) {
			kumuliertHaggisPunkte += haggisKarte.getPunkte();

		}

		System.out.println("kummulierte Punkte " + kumuliertHaggisPunkte);

		int gegnerischerPunkte = vierzehnKarten.size() * 5;
		System.out.println(" gegnerischerPunkte " + gegnerischerPunkte);
		int gesamtPunkte = spieler.getGesammeltenPunkte();
		gesammeltenPunkte = spieler.getGesammeltenPunkte()
				+ spielzustand.getUmkaempftePunkte() + kumuliertHaggisPunkte
				+ gesamtPunkte + gegnerischerPunkte;
		
		if (spieler.getGesammeltenPunkte() > gegenspieler
				.getGesammeltenPunkte()) {
			gegenspieler.setBlockiert(false);
			spieler.setBlockiert(true);
		} else {
			gegenspieler.setBlockiert(true);
			spieler.setBlockiert(false);
		}
		if (spieler.getGesammeltenPunkte() == gegenspieler
				.getGesammeltenPunkte()) {
			if (spieler.isRundenGewinner() == true) {
				spieler.setRundenBeginner(false);
				gegenspieler.setRundenBeginner(true);

			} else {
				spieler.setRundenBeginner(true);
				gegenspieler.setRundenBeginner(false);

			}

		}

		return gesammeltenPunkte;
	}

	public void stichGewinnerErmitteln(Spieler spieler1, Spieler spieler2,
			Spielzustand spielzustand) throws UnknownHostException,
			ClassNotFoundException, IOException {

		if (rundenGewinnerErmitteln(spieler1, spieler2, spielzustand)) {
			System.out.println("Rundengewinner");

		} else {
			int raengeSpieler1 = raengeErmitteln(spieler1
					.getZuSpielendenKarten());
			int raengeSpieler2 = raengeErmitteln(spieler2
					.getZuSpielendenKarten());

			if (raengeSpieler1 > raengeSpieler2) {

				spieler1.setStichGewinner(true);
				spieler2.setStichGewinner(false);
				spieler1.setBlockiert(false);
				spieler2.setBlockiert(true);

				stichpunktePunkteErmitteln(spieler1, spielzustand,
						spieler1.getZuSpielendenKarten());
			} else if (raengeSpieler1 < raengeSpieler2) {
				System.out.println("raengeSpieler1 " + raengeSpieler1
						+ " raengeSpieler2 " + raengeSpieler2);
				spieler2.setStichGewinner(true);
				spieler1.setStichGewinner(false);
				spieler2.setBlockiert(false);
				spieler1.setBlockiert(true);
				stichpunktePunkteErmitteln(spieler2, spielzustand,
						spieler1.getZuSpielendenKarten());

			} else if (raengeSpieler1 == raengeSpieler2) {
				System.out.println("Gleiche Raenge, Pattsituation");

			}
		}

	}

	public void stichpunktePunkteErmitteln(Spieler spieler,
			Spielzustand spielzustand, ArrayList<Karte> zuSpielendenKarten) {
		spielzustand.setUmkaempftePunkte(getPunkte(zuSpielendenKarten));

		int addierteStichpunkte = 0;

		addierteStichpunkte = spieler.getStichPunkte()
				+ spielzustand.getUmkaempftePunkte();
		spieler.setStichPunkte(addierteStichpunkte);
		
	}

	// diese Methode wird fuer Spiel starten gebraucht, sie kann durch
	// StichgewinnerErmitteln Methode aufgerufen werden oder direkt durch
	// aktives passen

	public boolean spielErlaubnisServer(Spieler spieler1, Spieler spieler2) {

		int raengeSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
		int raengeSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

		if (raengeSpieler1 == raengeSpieler2) {
			System.out
					.println("---------------------Raenge duerfen nicht gleich sein------------------");
			return false;
		}
		System.out.println("Ranglatte " + spielzustand.getRangLatte()
				+ " raengeSpieler1 " + raengeSpieler1 + " raengeSpieler2 "
				+ raengeSpieler2);
		if (raengeSpieler1 <= spielzustand.getRangLatte()
				&& raengeSpieler2 <= spielzustand.getRangLatte()) {
			System.out
					.println("------------------------Raenge kommen nicht ueber die Raengelatte--------------");
			return false;
		} else {
			spielzustand.setRangLatte(0);

		}

		System.out.println("------------------Strasse1 " + spieler1.isStrasse()
				+ " Strasse 2" + spieler2.isStrasse() + "--------");

		if (spieler1.getZuSpielendenKarten().size() == spieler2
				.getZuSpielendenKarten().size()) {
			System.out.println("spielErlaubnisServer 1");
			System.out.println("isSet Spieler 1 " + spieler1.isSet()
					+ " isSet Spieler 2 " + spieler2.isSet());
			if (spieler1.isSet() == true && spieler2.isSet() == true) {
				System.out
						.println("---------------------Server Set---------------------------");

				return true;

			} else if (spieler1.isStrasse() == true
					&& spieler2.isStrasse() == true) {
				System.out
						.println("--------Server Strasse------------------------");

				return true;

			} else if (spieler1.isEineKarte() == true
					&& spieler2.isEineKarte() == true) {
				System.out
						.println("----------------Server Eine Karte------------------");

				return true;
			}

		} else {
			if (spieler1.isGegnerHatGespielt() == true
					&& spieler2.isGegnerHatGespielt() == true) {
				System.out
						.println("--------------------Ungleiche Anzahl Karten auf beiden Seiten--------------------");
				return false;
			}
		}

		System.out.println("--------------------Einer spielt--------------------");
		return true;
	}

	public void spielen(Spieler spieler1, Spieler spieler2) {
		// System.out
		// .println("------------------spielen-------------------------");
		int rangSpieler1 = 0;
		int rangSpieler2 = 0;

		if (spieler1.isStrasse() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}

		if (spieler2.isStrasse() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}

		if (spieler1.isSet() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}
		if (spieler2.isSet() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}

		if (spieler1.isEineKarte() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}
		if (spieler2.isEineKarte() == true) {
			if (spieler1.getZuSpielendenKarten() != null)
				rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
			if (spieler2.getZuSpielendenKarten() != null)
				rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());

			// System.out.println("------------------spielen2-------------------------");

		}

		// if (spieler1.getZuSpielendenKarten() != null)
		// rangSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
		// if (spieler2.getZuSpielendenKarten() != null)
		// rangSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());
		//
		// System.out
		// .println("------------------spielen2-------------------------");

		if (rangSpieler1 > spielzustand.getRangLatte()) {

			// Latte hoeher setzen
			System.out
					.println("------------------------- Was ist neue RangLatte "
							+ rangSpieler1);
			spielzustand.setRangLatte(rangSpieler1);
			System.out.println("Ranglatte " + spielzustand.getRangLatte());
			spielzustand.setUmkaempftePunkte(spielzustand.getUmkaempftePunkte()
					+ getPunkte(spieler1.getZuSpielendenKarten()));
			// System.out.println("-----------------------------------umkaempfte Punkte Spieler 1 "
			// +spielzustand.getUmkaempftePunkte() );

		}
		if (rangSpieler2 > spielzustand.getRangLatte()) {

			System.out
					.println("-------------------------- Was ist neue RangLatte "
							+ rangSpieler2);
			spielzustand.setRangLatte(rangSpieler2);
			System.out.println("Ranglatte " + spielzustand.getRangLatte());
			spielzustand.setUmkaempftePunkte(spielzustand.getUmkaempftePunkte()
					+ getPunkte(spieler2.getZuSpielendenKarten()));
			// System.out.println("-----------------------------------umkaempfte Punkte Spieler2 "
			// +spielzustand.getUmkaempftePunkte() );
		}
	}

	// Hans
	

	// ein Spieler gibt die Runde auf
	public void passen(Spielzustand spielzustand, Spieler spieler1,
			Spieler spieler2) {
		System.out
				.println("---------------------------passen-------------------------------");
		int raengeSpieler1 = 0;
		int raengeSpieler2 = 0;
		getSpielzustand().setRangLatte(0);
		spielzustand.setRangLatte(0);
		System.out.println("Raenge werden zurueckgesetzt");
		
		System.out
				.println("Ranglatte sollte zurueckgesetzt sein---------------"
						+ getSpielzustand().getRangLatte());
		System.out
				.println("Ranglatte sollte zurueckgesetzt sein---------------"
						+ spielzustand.getRangLatte());

		if (spieler1.getZuSpielendenKarten() != null) {
			raengeSpieler1 = raengeErmitteln(spieler1.getZuSpielendenKarten());
		}
		if (spieler2.getZuSpielendenKarten() != null) {
			raengeSpieler2 = raengeErmitteln(spieler2.getZuSpielendenKarten());
		}
		// System.out
		// .println("--------------------------------passen 2-----------------------------");

		if (raengeSpieler1 > raengeSpieler2) {
			spieler1.setGesammeltenPunkte(spieler1.getGesammeltenPunkte()
					+ spielzustand.getUmkaempftePunkte());
			// System.out.println("Spieler 1 seine Gesamtpuntke -------------------------- "
			// + spieler1.getGesammeltenPunkte());
			// System.out
			// .println("--------------------------------passen 3-----------------------------");

			spieler1.setStichGewinner(true);
			spieler2.setStichGewinner(false);
		}

		else if (raengeSpieler1 < raengeSpieler2) {
			spieler2.setGesammeltenPunkte(spieler2.getGesammeltenPunkte()
					+ spielzustand.getUmkaempftePunkte());
			// System.out.println("Spieler 2 seine Gesamtpuntke -------------------------- "
			// + spieler2.getGesammeltenPunkte());
			// System.out
			// .println("--------------------------------passen 4-----------------------------");
			spieler2.setStichGewinner(true);
			spieler1.setStichGewinner(false);

		}
		// System.out
		// .println("--------------------------------passen 5-----------------------------");
		spielzustand.setUmkaempftePunkte(0);
		spieler1.setGegnerHatGespielt(false);
		spieler2.setGegnerHatGespielt(false);

		spieler1.setSet(false);
		spieler2.setSet(false);
		spieler1.setStrasse(false);
		spieler2.setStrasse(false);
		spieler1.setEineKarte(false);
		spieler2.setEineKarte(false);

	}

	// if (zuSpielendeKarten!=null) { zuSpielendeKarten=new ArrayList<?>(); }
	public int raengeErmitteln(ArrayList<Karte> zuSpielendeKarten) {

		Collections.sort(zuSpielendeKarten);

		if (zuSpielendeKarten.size() != 0 && getSet(zuSpielendeKarten)) {
			int rang = zuSpielendeKarten.get(0).getRang();
			return rang * zuSpielendeKarten.size();
		}

		ArrayList<Karte> normaleKarten = new ArrayList<Karte>();
		ArrayList<Karte> jokerKarten = new ArrayList<Karte>();

		// trenne zwischen Jokker und normalen Karten
		for (Karte karte : zuSpielendeKarten) {
			if (karte.isJoker()) {
				jokerKarten.add(karte);
			} else {
				normaleKarten.add(karte);
			}
		}

		// ermittel kleinster Rang
		int j = 0;
		int kleinsterRang = 0;
		for (Karte karte : normaleKarten) {
			if (karte.getRang() != j) {
				kleinsterRang = karte.getRang();
				break;
			}
		}
		int hoechsterRang = 0;

		// ermittel fehlende Raenge
		for (Karte karte : normaleKarten) {
			if (karte.getRang() != j) {
				hoechsterRang = karte.getRang();

			}

		}

		ArrayList<Integer> paerchen = new ArrayList<>();

		// erzeuge Karten
		int rangCounter = kleinsterRang;

		ArrayList<Raenge> raenge = new ArrayList<>();
		while (rangCounter <= hoechsterRang) {
			raenge.add(new Raenge(rangCounter, 0));
			rangCounter++;
		}

		for (int i = 0; i < 10; i++) {
			int paerchenGroesse = 0;
			for (Karte karte : normaleKarten) {
				if (karte.getRang() == (i + 2)) {
					raenge = raengeKumulieren(karte.getRang(), raenge);
				}
			}
		}
		int max = 0;
		for (Raenge rang : raenge) {
			System.out.println("Rang " + rang.getRang() + " Ranggroesse "
					+ rang.getRangGroesse());
			if (rang.getRangGroesse() > max) {
				max = rang.getRangGroesse();
			}
		}

		int kumulierteRaenge = 0;

		for (Raenge rang : raenge) {
			kumulierteRaenge += (max * rang.getRang());
		}

		System.out.println("Max " + max);

		// ermittel gesuchte Jokerkarten
		int gesuchteJokerKarten = 0;
		for (Raenge rang : raenge) {
			gesuchteJokerKarten += (max - rang.getRangGroesse());

		}

		int rest = jokerKarten.size() - gesuchteJokerKarten;

		int t = 0;
		while (max == 1 && t < rest) {
			t++;
			System.out.println("t " + t + " Rest " + rest);
			kumulierteRaenge += (hoechsterRang + t);

		}
		t = 0;
		if (max >= 2 && rest > 0) {
			t++;
			System.out.println("rang " + (hoechsterRang + t));
			kumulierteRaenge += (max * (hoechsterRang + t));
		}

		System.out.println("Gesuchte Jokerkarten " + gesuchteJokerKarten);

		return kumulierteRaenge;
	}

	public ArrayList<Raenge> raengeKumulieren(int vorhandenerRang,
			ArrayList<Raenge> raenge) {
		for (Raenge rang : raenge) {
			if (vorhandenerRang == rang.getRang()) {
				rang.setRangGroesse(rang.getRangGroesse() + 1);
			}
		}

		return raenge;
	}

}